{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "28b9c35e-ebf2-4198-a743-4ef229abc06f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n",
      "24\n",
      "[12 15 18]\n",
      "[2. 5. 8.]\n",
      "2.581988897471611\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "arr = np.array([1, 2, 3, 4])\n",
    "\n",
    "# 求和\n",
    "print(np.sum(arr))  # 输出: 10\n",
    "\n",
    "# 求积\n",
    "print(np.prod(arr))  # 输出: 24 (1*2*3*4)\n",
    "\n",
    "\n",
    "arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n",
    "\n",
    "# 沿列求和(axis=0)\n",
    "print(np.sum(arr_2d, axis=0))  # 输出: [12 15 18]\n",
    "\n",
    "# 沿行求平均值(axis=1)\n",
    "print(np.mean(arr_2d, axis=1))  # 输出: [2. 5. 8.]\n",
    "\n",
    "# 整个数组的标准差\n",
    "print(np.std(arr_2d))  # 输出: 2.581988897471611\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5eb0238d-f2a1-4fe9-a708-d8890fa3e0f4",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2a9e4223-0a19-4633-9a5c-8e1675491b46",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(3.0)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "arr = np.array([1, 2, 3, 4, 5])\n",
    "np.mean(arr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e7cc1f44-0e39-4cd0-9201-bb884e5d5469",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "2d85e680-d7c7-4d4b-a1e2-dfd2d3164364",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1.  2.  3. nan]\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([3, np.nan, 1, 2])\n",
    "print(np.sort(arr))  # [ 1.  2.  3. nan]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "27802eb6-1c8f-498a-9b55-3c142cf7b16f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 3. nan  1.  2.]\n",
      "[ 1.  2.  3. nan]\n"
     ]
    }
   ],
   "source": [
    "print(arr)\n",
    "arr.sort()\n",
    "print(arr)  # [ 1.  2.  3. nan]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73d09c4e-2857-49c6-8fb3-7f6c9e622197",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "05e26b12-6adb-4009-8142-101175861b08",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.0\n",
      "3.2\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "# 简单平均值\n",
    "print(np.mean(arr))  # 输出: 3.0\n",
    "\n",
    "# 加权平均值\n",
    "weights = np.array([0.1, 0.2, 0.3, 0.2, 0.2])\n",
    "print(np.average(arr, weights=weights))  # 输出: 3.2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "feed8be6-bb4b-40dc-b633-bc4ee0c0111c",
   "metadata": {},
   "source": [
    "### 标准差和方差是统计学中用于衡量数据离散程度（即数据波动性或稳定性）的核心指标，两者密切相关但用途略有差异\n",
    "\n",
    "### 定义：方差反映数据点与均值的平均平方偏差，用于量化数据围绕平均值的波动幅度。方差越大，数据越分散；方差越小，数据越集中\n",
    "### 两者是数据分析的基石，广泛应用于风险评估、质量控制、科研实验等领域，帮助决策者理解数据分布与稳定性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "2fabe3c6-b750-4858-aa41-85e79f9846a8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.4142135623730951\n",
      "2.0\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "arr = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "# 标准差\n",
    "print(np.std(arr))  # 输出: 1.4142135623730951\n",
    "\n",
    "# 方差\n",
    "print(np.var(arr))  # 输出: 2.0\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f219049c-761d-4696-b50e-9519c30fda80",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b1ee4585-44df-4406-9d5e-000b99e7e4b1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "1\n",
      "9\n",
      "9\n",
      "1\n",
      "5\n",
      "3.5714285714285716\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "arr = np.array([3, 1, 4, 1, 5, 9, 2])\n",
    "\n",
    "# 最小值\n",
    "print(np.min(arr))  # 输出: 1\n",
    "print(np.amin(arr))  # 同上\n",
    "\n",
    "# 最大值\n",
    "print(np.max(arr))  # 输出: 9\n",
    "print(np.amax(arr))  # 同上\n",
    "\n",
    "# 最小值位置\n",
    "print(np.argmin(arr))  # 输出: 1 (第一个1的位置)\n",
    "\n",
    "# 最大值位置\n",
    "print(np.argmax(arr))  # 输出: 5 (9的位置)\n",
    "\n",
    "\n",
    "# 简单平均值\n",
    "print(np.mean(arr))  # 输出: 3.0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "3ef8af7b-6f30-41ca-a30e-01bb1530fe96",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5.0\n",
      "3.5\n",
      "3.5\n",
      "7.5\n",
      "7.5\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])\n",
    "\n",
    "# 中位数  偶数，就是2数和除以2\n",
    "print(np.median(arr))  # 输出: 5.5\n",
    "\n",
    "# 百分位数/分位数\n",
    "print(np.percentile(arr, 25))  # 25百分位数(第一四分位数)\n",
    "print(np.quantile(arr, 0.25))  # 同上，输出: 3.25\n",
    "\n",
    "print(np.percentile(arr, 75))  # 75百分位数(第三四分位数)\n",
    "print(np.quantile(arr, 0.75))  # 同上，输出: 7.75\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bdf2bc9c-198e-4afc-a8a5-e074f7012613",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "077ffe7c-ed7c-45ac-81e4-224e5130387f",
   "metadata": {},
   "source": [
    "# np.all(): 所有元素是否为 True。\n",
    "\n",
    "# np.any(): 是否有任一元素为 True。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5ef4c92c-e4ba-4546-8ef8-91b773ae7122",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "dfa4a218-7248-42a1-b730-6961b1450619",
   "metadata": {},
   "source": [
    " # 返回排序后的数组副本，不修改原数组，可以指定排序轴和排序算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "0a7e062a-b3b9-4c9f-8775-c3188d62fb41",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原数组: [3 1 4 2 5]\n",
      "排序后: [1 2 3 4 5]\n",
      "按行排序:\n",
      " [[1 3 4]\n",
      " [1 5 9]\n",
      " [2 5 6]]\n",
      "按列排序:\n",
      " [[1 1 4]\n",
      " [2 5 5]\n",
      " [3 6 9]]\n",
      "快速排序: [0 0 0 0 0]\n",
      "归并排序: [0 0 0 0 0]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# 一维数组排序\n",
    "arr = np.array([3, 1, 4, 2, 5])\n",
    "sorted_arr = np.sort(arr)  # 返回新数组\n",
    "print(\"原数组:\", arr)       # [3 1 4 2 5]\n",
    "print(\"排序后:\", sorted_arr) # [1 2 3 4 5]\n",
    "\n",
    "# 二维数组按行排序\n",
    "arr_2d = np.array([[3, 1, 4], [1, 5, 9], [2, 6, 5]])\n",
    "print(\"按行排序:\\n\", np.sort(arr_2d, axis=1))\n",
    "\"\"\"\n",
    "[[1 3 4]\n",
    " [1 5 9]\n",
    " [2 5 6]]\n",
    "\"\"\"\n",
    "\n",
    "# 二维数组按列排序\n",
    "print(\"按列排序:\\n\", np.sort(arr_2d, axis=0))\n",
    "\"\"\"\n",
    "[[1 1 4]\n",
    " [2 5 5]\n",
    " [3 6 9]]\n",
    "\"\"\"\n",
    "\n",
    "# 使用不同排序算法\n",
    "large_arr = np.random.randint(0, 1000, 10000)\n",
    "print(\"快速排序:\", np.sort(large_arr, kind='quicksort')[:5])  # 前5个元素\n",
    "print(\"归并排序:\", np.sort(large_arr, kind='mergesort')[:5])\n",
    "\n",
    "# axis: 沿哪个轴排序，默认为-1（最后一个轴）\n",
    "# kind: 排序算法，可选 'quicksort', 'mergesort', 'heapsort', 'stable'\n",
    "# order: 当数组是结构化数组时，指定排序字段"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32076c6a-35b1-4982-aa22-b9da261efee6",
   "metadata": {},
   "source": [
    "# 对数组进行原地排序，不创建副本\n",
    "\n",
    "# 修改原数组内容\n",
    "\n",
    "# 参数与np.sort()相同"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "96245db5-b661-4fce-89eb-f524b53f4fff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "排序前: [3 1 4 2 5]\n",
      "排序后: [1 2 3 4 5]\n",
      "列排序后:\n",
      " [[3 1]\n",
      " [4 2]]\n",
      "行排序后:\n",
      " [[1 3]\n",
      " [2 4]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'\\n[[1 3]\\n [2 4]]\\n'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr = np.array([3, 1, 4, 2, 5])\n",
    "print(\"排序前:\", arr)  # [3 1 4 2 5]\n",
    "arr.sort()           # 原地排序\n",
    "print(\"排序后:\", arr)  # [1 2 3 4 5]\n",
    "\n",
    "# 多维数组原地排序\n",
    "arr_2d = np.array([[3, 1], [4, 2]])\n",
    "arr_2d.sort(axis=0)  # 沿列排序\n",
    "print(\"列排序后:\\n\", arr_2d)\n",
    "\"\"\"\n",
    "[[3 1]\n",
    " [4 2]]\n",
    "\"\"\"\n",
    "\n",
    "arr_2d.sort(axis=1)  # 沿行排序\n",
    "print(\"行排序后:\\n\", arr_2d)\n",
    "\"\"\"\n",
    "[[1 3]\n",
    " [2 4]]\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e77d200-3dbf-4673-84c4-258b647216d2",
   "metadata": {},
   "source": [
    "# 返回对数组排序的索引数组\n",
    "\n",
    "# 不修改原数组，返回的是索引值\n",
    "\n",
    "# 可用于通过索引获取排序后的数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2ac5773f-d40c-4ac4-9208-d15f8647b920",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原数组: [3 1 4 2 5]\n",
      "排序索引: [1 3 0 2 4]\n",
      "通过索引获取排序数组: [1 2 3 4 5]\n",
      "按第一列排序的索引: [1 2 0]\n",
      "排序后数组:\n",
      " [[1 5]\n",
      " [2 6]\n",
      " [3 1]]\n",
      "前三名索引: [4 0 2]\n",
      "前三名分数: [90 92 97]\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([3, 1, 4, 2, 5])\n",
    "indices = np.argsort(arr)\n",
    "print(\"原数组:\", arr)        # [3 1 4 2 5]\n",
    "print(\"排序索引:\", indices)   # [1 3 0 2 4]\n",
    "print(\"通过索引获取排序数组:\", arr[indices])  # [1 2 3 4 5]\n",
    "\n",
    "# 按某列排序二维数组\n",
    "data = np.array([[3, 1], [1, 5], [2, 6]])\n",
    "# 按第一列排序\n",
    "sort_indices = np.argsort(data[:, 0])\n",
    "print(\"按第一列排序的索引:\", sort_indices)  # [1 2 0]\n",
    "print(\"排序后数组:\\n\", data[sort_indices])\n",
    "\"\"\"\n",
    "[[1 5]\n",
    " [2 6]\n",
    " [3 1]]\n",
    "\"\"\"\n",
    "\n",
    "# 按值大小获取前N个元素的索引\n",
    "scores = np.array([92, 85, 97, 89, 90])\n",
    "top3_indices = np.argsort(scores)[-3:]  # 获取最大的3个索引\n",
    "print(\"前三名索引:\", top3_indices)  # [1 4 2]\n",
    "print(\"前三名分数:\", scores[top3_indices])  # [85 90 97]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d4648fc-e1b7-4b6a-881b-bd7eb50907f5",
   "metadata": {},
   "source": [
    "# 使用键序列执行间接稳定排序\n",
    "\n",
    "# 相当于Excel中的多列排序\n",
    "\n",
    "# 最后一个键是主排序键"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "9d09073b-5466-4210-9440-5bfdb32f369e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "排序索引: [1 3 2 0 4]\n",
      "Li Lei\n",
      "Li Xiang\n",
      "Wang Fang\n",
      "Zhang Hui\n",
      "Zhang Jing\n",
      "多列排序结果:\n",
      " [[2 3 1]\n",
      " [2 3 2]\n",
      " [3 1 5]\n",
      " [3 2 3]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'\\n[[2 3 1]\\n [2 3 2]\\n [3 1 5]\\n [3 2 3]]\\n'"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按姓氏排序，同姓氏按名字排序\n",
    "surnames = np.array(['Zhang', 'Li', 'Wang', 'Li', 'Zhang'])\n",
    "firstnames = np.array(['Hui', 'Lei', 'Fang', 'Xiang', 'Jing'])\n",
    "# 注意：lexsort的键顺序是反的，最后面的键是主键\n",
    "indices = np.lexsort((firstnames, surnames))\n",
    "print(\"排序索引:\", indices)  # [1 3 4 0 2]\n",
    "\n",
    "# 显示排序结果\n",
    "for i in indices:\n",
    "    print(surnames[i], firstnames[i])\n",
    "\"\"\"\n",
    "Li Lei\n",
    "Li Xiang\n",
    "Zhang Jing\n",
    "Zhang Hui\n",
    "Wang Fang\n",
    "\"\"\"\n",
    "\n",
    "# 多列数据排序\n",
    "data = np.array([\n",
    "    [3, 1, 5],  # 假设三列分别是年龄、分数、ID\n",
    "    [2, 3, 1],\n",
    "    [3, 2, 3],\n",
    "    [2, 3, 2]\n",
    "])\n",
    "# 先按年龄(第0列)排序，同年龄按分数(第1列)排序，最后按ID(第2列)排序\n",
    "sorted_indices = np.lexsort((data[:, 2], data[:, 1], data[:, 0]))\n",
    "print(\"多列排序结果:\\n\", data[sorted_indices])\n",
    "\"\"\"\n",
    "[[2 3 1]\n",
    " [2 3 2]\n",
    " [3 1 5]\n",
    " [3 2 3]]\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "24a7bea9-20ce-4db4-aa87-a35cc0f1d24d",
   "metadata": {},
   "source": [
    "# 将数组分为两部分，前k小的元素在左边，其余在右边\n",
    "\n",
    "# 不保证左边或右边部分的内部顺序\n",
    "\n",
    "# 比完全排序更高效，适合只需要前k个元素的场景"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "34d9c437-20cc-4980-83ba-31e01cb5840c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "分区后: [1 2 3 4 5 6 7 9]\n",
      "前3小: [1 2 3]\n",
      "前3小元素索引: [1 3 0]\n",
      "前3小元素值: [1 2 3]\n",
      "最大的3个元素索引: [7 6 5]\n",
      "最大的3个元素: [6 7 9]\n",
      "每行前2小:\n",
      " [[1 3]\n",
      " [2 5]\n",
      " [3 5]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'\\n[[1 3]\\n [2 5]\\n [3 5]]\\n'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr = np.array([3, 1, 4, 2, 5, 9, 7, 6])\n",
    "\n",
    "# 找出前3小的元素（不排序）\n",
    "partitioned = np.partition(arr, 3)\n",
    "print(\"分区后:\", partitioned)  # 前3小的在左边，顺序不定\n",
    "# 可能输出: [1 2 3 4 5 9 7 6]\n",
    "print(\"前3小:\", partitioned[:3])  # 前3小的元素\n",
    "\n",
    "# 获取前3小元素的索引\n",
    "indices = np.argpartition(arr, 3)\n",
    "print(\"前3小元素索引:\", indices[:3])  # 如 [1 3 0]\n",
    "print(\"前3小元素值:\", arr[indices[:3]])\n",
    "\n",
    "# 找出最大的3个元素\n",
    "indices = np.argpartition(arr, -3)[-3:]  # 最大的3个索引\n",
    "print(\"最大的3个元素索引:\", indices)  # 如 [6 4 5]\n",
    "print(\"最大的3个元素:\", arr[indices])\n",
    "\n",
    "# 二维数组应用\n",
    "arr_2d = np.array([[3, 1, 4], [5, 9, 2], [6, 5, 3]])\n",
    "# 每行找出前2小的元素\n",
    "partitioned = np.partition(arr_2d, 2, axis=1)\n",
    "print(\"每行前2小:\\n\", partitioned[:, :2])\n",
    "\"\"\"\n",
    "[[1 3]\n",
    " [2 5]\n",
    " [3 5]]\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "76745e27-d33e-44b1-b0f7-0372babec38c",
   "metadata": {},
   "source": [
    "# 在已排序数组中查找插入位置以维持排序\n",
    "\n",
    "# 可用于将新元素插入到已排序数组中\n",
    "\n",
    "# 支持左侧和右侧插入位置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "7247050e-29d2-44d3-8a3a-8f5596f98874",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4应插入的位置: 2\n",
      "插入位置: [1 2 3 4]\n",
      "插入后数组: [1 2 3 4 5 6 7 8 9]\n",
      "插入2的位置(left): 1\n",
      "插入2的位置(right): 3\n"
     ]
    }
   ],
   "source": [
    "sorted_arr = np.array([1, 3, 5, 7, 9])\n",
    "\n",
    "# 查找单个元素的插入位置\n",
    "pos = np.searchsorted(sorted_arr, 4)\n",
    "print(\"4应插入的位置:\", pos)  # 2 (在3和5之间)\n",
    "\n",
    "# 插入多个元素\n",
    "new_elements = np.array([2, 4, 6, 8])\n",
    "positions = np.searchsorted(sorted_arr, new_elements)\n",
    "print(\"插入位置:\", positions)  # [1 2 3 4]\n",
    "\n",
    "# 实际插入操作\n",
    "result = np.insert(sorted_arr, positions, new_elements)\n",
    "print(\"插入后数组:\", result)  # [1 2 3 4 5 6 7 8 9]\n",
    "\n",
    "# 使用side参数控制插入位置\n",
    "# side='right'会在相等元素后插入\n",
    "arr = np.array([1, 2, 2, 3, 5])\n",
    "print(\"插入2的位置(left):\", np.searchsorted(arr, 2))  # 1\n",
    "print(\"插入2的位置(right):\", np.searchsorted(arr, 2, side='right'))  # 3\n",
    "\n",
    "# # 在二维数组每行中查找\n",
    "# sorted_2d = np.array([[1, 3, 5], [2, 4, 6]])\n",
    "# values = np.array([[2, 4], [3, 5]])\n",
    "# positions = np.searchsorted(sorted_2d, values, axis=1)\n",
    "# print(\"二维查找结果:\\n\", positions)\n",
    "# \"\"\"\n",
    "# [[1 2]\n",
    "#  [1 2]]\n",
    "# \"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8cb2c2ff-2039-4275-bb1c-107b2c504756",
   "metadata": {},
   "source": [
    "![](./1751722589434.jpg)\n",
    "<!-- <img src=\"./1751722589434.jpg\", width=320, heigth=240> -->"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f320ff7-0a84-45a8-9f70-096a3d87f85c",
   "metadata": {},
   "source": [
    "\n",
    "![jupyter](./1751723416197.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0755721-4135-4544-a8c5-3141be5d69a9",
   "metadata": {},
   "source": [
    "# 返回数组沿指定轴的最大值/最小值的索引\n",
    "\n",
    "# 对于平铺后的数组（即不指定轴），返回全局极值索引\n",
    "\n",
    "# 如果有多个相同极值，返回第一个出现的索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "7afd4bca-0574-497a-a950-88eb79400577",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最大值索引: 5\n",
      "最小值索引: 1\n",
      "每列最大值索引: [0 2 1]\n",
      "每行最小值索引: [1 0 0]\n",
      "多个最大值时返回第一个: 2\n",
      "1\n",
      "忽略NaN的最大值索引: 5\n",
      "忽略NaN的最小值索引: 2\n",
      "每列忽略NaN的最大值索引: [0 2 1]\n",
      "每行忽略NaN的最小值索引: [0 1 0]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# 一维数组示例\n",
    "arr = np.array([3, 1, 4, 1, 5, 9, 2])\n",
    "print(\"最大值索引:\", np.argmax(arr))  # 5 (9的位置)\n",
    "print(\"最小值索引:\", np.argmin(arr))  # 1 (第一个1的位置)\n",
    "\n",
    "# 二维数组示例\n",
    "arr_2d = np.array([[3, 1, 4], \n",
    "                   [1, 5, 9], \n",
    "                   [2, 6, 5]])\n",
    "\n",
    "# 沿轴0(列方向)的最大值索引\n",
    "print(\"每列最大值索引:\", np.argmax(arr_2d, axis=0))  # [0 2 1]\n",
    "\n",
    "# 沿轴1(行方向)的最小值索引\n",
    "print(\"每行最小值索引:\", np.argmin(arr_2d, axis=1))  # [1 0 0]\n",
    "\n",
    "# 多个相同极值的情况\n",
    "arr_dup = np.array([1, 2, 3, 3, 2, 1])\n",
    "print(\"多个最大值时返回第一个:\", np.argmax(arr_dup))  # 2\n",
    "\n",
    "\n",
    "\n",
    "# 与argmax/argmin类似，但忽略NaN值\n",
    "# 适用于包含缺失值的数据分析\n",
    "\n",
    "arr_nan = np.array([3, np.nan, 1, 4, np.nan, 5])\n",
    "\n",
    "# 普通argmax遇到NaN会出错\n",
    "try:\n",
    "    print(np.argmax(arr_nan))\n",
    "except Exception as e:\n",
    "    print(\"错误:\", e)  # 会报错\n",
    "\n",
    "# 使用nanargmax\n",
    "print(\"忽略NaN的最大值索引:\", np.nanargmax(arr_nan))  # 5 (值为5)\n",
    "print(\"忽略NaN的最小值索引:\", np.nanargmin(arr_nan))  # 2 (值为1)\n",
    "\n",
    "# 二维数组应用\n",
    "arr_2d_nan = np.array([[3, np.nan, 4], \n",
    "                       [np.nan, 5, 9], \n",
    "                       [2, 6, np.nan]])\n",
    "\n",
    "print(\"每列忽略NaN的最大值索引:\", np.nanargmax(arr_2d_nan, axis=0))  # [0 2 1]\n",
    "print(\"每行忽略NaN的最小值索引:\", np.nanargmin(arr_2d_nan, axis=1))  # [0 1 0]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20651c65-9b7a-45b0-af9c-266337f60ee4",
   "metadata": {},
   "source": [
    "# 形式1：np.where(condition) - 返回满足条件的元素索引\n",
    "\n",
    "# 形式2：np.where(condition, x, y) - 根据条件从x或y中选择元素\n",
    "\n",
    "# 类似于三元表达式，但支持数组操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "8dec31eb-e280-4e4e-8935-884347bff857",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "大于3的索引: (array([3, 4]),)\n",
      "大于3的值: [4 5]\n",
      "偶数的行索引: [0 1 1]\n",
      "偶数的列索引: [1 0 2]\n",
      "偶数值: [2 4 6]\n",
      "条件选择结果: [ 1 20  3 40]\n",
      "修改后数组:\n",
      " [[1 2 3]\n",
      " [0 0 0]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'\\n[[1 2 3]\\n [0 0 0]]\\n'"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 形式1：查找满足条件的索引\n",
    "arr = np.array([1, 2, 3, 4, 5])\n",
    "indices = np.where(arr > 3)\n",
    "print(\"大于3的索引:\", indices)  # (array([3, 4], dtype=int64),)\n",
    "print(\"大于3的值:\", arr[indices])  # [4 5]\n",
    "\n",
    "# 二维数组示例\n",
    "arr_2d = np.array([[1, 2, 3], \n",
    "                   [4, 5, 6]])\n",
    "rows, cols = np.where(arr_2d % 2 == 0)\n",
    "print(\"偶数的行索引:\", rows)  # [0 1 1]\n",
    "print(\"偶数的列索引:\", cols)  # [1 0 2]\n",
    "print(\"偶数值:\", arr_2d[rows, cols])  # [2 4 6]\n",
    "\n",
    "# 形式2：条件选择\n",
    "x = np.array([1, 2, 3, 4])\n",
    "y = np.array([10, 20, 30, 40])\n",
    "condition = np.array([True, False, True, False])\n",
    "result = np.where(condition, x, y)\n",
    "print(\"条件选择结果:\", result)  # [1 20 3 40]\n",
    "\n",
    "# 实际应用：将数组中大于3的值设为0，其余保持原样\n",
    "arr = np.array([[1, 2, 3], \n",
    "                [4, 5, 6]])\n",
    "modified = np.where(arr > 3, 0, arr)\n",
    "print(\"修改后数组:\\n\", modified)\n",
    "\"\"\"\n",
    "[[1 2 3]\n",
    " [0 0 0]]\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15aa4b23-9d6b-4a50-8d51-878797700234",
   "metadata": {},
   "source": [
    "# 返回数组中非零元素的索引\n",
    "\n",
    "# 对于多维数组，返回每个维度的索引数组组成的元组\n",
    "\n",
    "# 类似于where(arr != 0)，但更高效"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "dfe9ef1f-2e95-49d1-ab3a-5c353d4aa4a1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "非零元素索引: (array([1, 3, 5]),)\n",
      "非零元素值: [1 3 5]\n",
      "非零元素的行: [0 1 1 2]\n",
      "非零元素的列: [1 0 2 2]\n",
      "非零元素值: [1 2 3 4]\n",
      "where结果: (array([1, 1, 2]), array([0, 2, 2]))\n",
      "nonzero结果: (array([1, 1, 2]), array([0, 2, 2]))\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([0, 1, 0, 3, 0, 5])\n",
    "nonzero_indices = np.nonzero(arr)\n",
    "print(\"非零元素索引:\", nonzero_indices)  # (array([1, 3, 5], dtype=int64),)\n",
    "print(\"非零元素值:\", arr[nonzero_indices])  # [1 3 5]\n",
    "\n",
    "# 二维数组示例\n",
    "arr_2d = np.array([[0, 1, 0], \n",
    "                   [2, 0, 3], \n",
    "                   [0, 0, 4]])\n",
    "rows, cols = np.nonzero(arr_2d)\n",
    "print(\"非零元素的行:\", rows)  # [0 1 1 2]\n",
    "print(\"非零元素的列:\", cols)  # [1 0 2 2]\n",
    "print(\"非零元素值:\", arr_2d[rows, cols])  # [1 2 3 4]\n",
    "\n",
    "# 与where的区别\n",
    "bool_arr = arr_2d > 1\n",
    "print(\"where结果:\", np.where(bool_arr))  # 与nonzero(bool_arr)相同\n",
    "print(\"nonzero结果:\", np.nonzero(bool_arr))  # 相同结果"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e57ecb08-481a-413a-a249-3c62fc457637",
   "metadata": {},
   "source": [
    "# 计算数组中非零元素的数量\n",
    "\n",
    "# 可以沿指定轴计算\n",
    "\n",
    "# 对于布尔数组，计算True的数量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "47823f8a-2a6a-4a98-bd9a-3ce20e27ea40",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "非零元素数量: 3\n",
      "整个数组的非零数: 4\n",
      "每行的非零数: [1 2 1]\n",
      "每列的非零数: [1 1 2]\n",
      "True的数量: 3\n",
      "大于5的元素数量: 4\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([0, 1, 0, 3, 0, 5])\n",
    "print(\"非零元素数量:\", np.count_nonzero(arr))  # 3\n",
    "\n",
    "# 二维数组示例\n",
    "arr_2d = np.array([[0, 1, 0], \n",
    "                   [2, 0, 3], \n",
    "                   [0, 0, 4]])\n",
    "print(\"整个数组的非零数:\", np.count_nonzero(arr_2d))  # 4\n",
    "print(\"每行的非零数:\", np.count_nonzero(arr_2d, axis=1))  # [1 2 1]\n",
    "print(\"每列的非零数:\", np.count_nonzero(arr_2d, axis=0))  # [1 1 2]\n",
    "\n",
    "# 布尔数组应用\n",
    "bool_arr = np.array([True, False, True, True])\n",
    "print(\"True的数量:\", np.count_nonzero(bool_arr))  # 3\n",
    "\n",
    "# 条件计数\n",
    "arr = np.random.randint(0, 10, (3, 4))\n",
    "print(\"大于5的元素数量:\", np.count_nonzero(arr > 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "046d8431-6d50-4fc4-8a79-4e440f304b04",
   "metadata": {},
   "source": [
    "# 找到数组的唯一值（去重）\n",
    "\n",
    "# 可以返回唯一值的索引、计数和反向索引\n",
    "\n",
    "# 支持多维数组（会先展平）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "369fe1cc-8703-4f86-a2ab-5ec3a0399ade",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "唯一值: [1 2 3 4]\n",
      "首次出现索引: [1 2 0 6]\n",
      "出现次数: [2 2 2 1]\n",
      "二维数组唯一值: [1 2 3]\n",
      "按行唯一: [array([1, 2, 3]), array([1, 2, 3])]\n",
      "唯一人员: [(b'Alice', 25) (b'Bob', 30)]\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([3, 1, 2, 2, 3, 1, 4])\n",
    "unique_values = np.unique(arr)\n",
    "print(\"唯一值:\", unique_values)  # [1 2 3 4]\n",
    "\n",
    "# 返回索引和计数\n",
    "unique_values, indices, counts = np.unique(arr, \n",
    "                                         return_index=True, \n",
    "                                         return_counts=True)\n",
    "print(\"首次出现索引:\", indices)  # [1 2 0 6]\n",
    "print(\"出现次数:\", counts)     # [2 2 2 1]\n",
    "\n",
    "# 二维数组应用\n",
    "arr_2d = np.array([[1, 2, 3], \n",
    "                   [3, 2, 1]])\n",
    "print(\"二维数组唯一值:\", np.unique(arr_2d))  # [1 2 3]\n",
    "\n",
    "# 按行唯一\n",
    "print(\"按行唯一:\", [np.unique(row) for row in arr_2d])\n",
    "\n",
    "# 结构化数组\n",
    "dt = np.dtype([('name', 'S10'), ('age', int)])\n",
    "people = np.array([('Alice', 25), ('Bob', 30), ('Alice', 25)], dtype=dt)\n",
    "unique_people = np.unique(people)\n",
    "print(\"唯一人员:\", unique_people)  # [(b'Alice', 25) (b'Bob', 30)]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75f8a61c-9dec-4106-a8a9-f650cba23379",
   "metadata": {},
   "source": [
    "# 测试数组中的每个元素是否在另一个数组中\n",
    "\n",
    "# 返回布尔数组，形状与第一个参数相同\n",
    "\n",
    "# 可用于数据过滤和分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "b3b4079e-d059-45dc-984c-6d5d67bac33d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "成员测试结果: [False  True False  True False]\n",
      "匹配的元素: [2 4]\n",
      "不在集合中的元素: [1 3 5]\n",
      "二维成员测试:\n",
      " [[False  True False]\n",
      " [ True False  True]]\n",
      "属于分类的水果: ['apple' 'orange' 'apple']\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([1, 2, 3, 4, 5])\n",
    "test_elements = np.array([2, 4, 6])\n",
    "mask = np.isin(arr, test_elements)\n",
    "print(\"成员测试结果:\", mask)  # [False  True False  True False]\n",
    "print(\"匹配的元素:\", arr[mask])  # [2 4]\n",
    "\n",
    "# 逆操作\n",
    "print(\"不在集合中的元素:\", arr[~mask])  # [1 3 5]\n",
    "\n",
    "# 二维数组应用\n",
    "arr_2d = np.array([[1, 2, 3], \n",
    "                   [4, 5, 6]])\n",
    "print(\"二维成员测试:\\n\", np.isin(arr_2d, [2, 4, 6]))\n",
    "\"\"\"\n",
    "[[False  True False]\n",
    " [ True False  True]]\n",
    "\"\"\"\n",
    "\n",
    "# 高级应用：分类\n",
    "data = np.array(['apple', 'banana', 'orange', 'apple', 'pear'])\n",
    "categories = np.array(['apple', 'orange'])\n",
    "is_fruit = np.isin(data, categories)\n",
    "print(\"属于分类的水果:\", data[is_fruit])  # ['apple' 'orange' 'apple']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "27d47aac-d56d-4bfe-9eca-ac692f806e08",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "63cf2da8-590d-4aae-9160-3bcf9fabbd47",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "8dbe5f88-87ed-41f9-b8d6-06286166d6e2",
   "metadata": {},
   "source": [
    "\n",
    "![jupyter](./1751723416197.jpg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e7890cb9-3556-401d-9253-b5784da2a7c9",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bb6bb7c2-0a3b-4950-a39a-def445871b49",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fb5037c8-ada5-4f10-8cd7-7320ff49c2d1",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "84d892b5-a38b-48e9-a98b-6eda4a25d93e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dfbcd55b-0a76-4d6a-ac2a-dbc8103a9781",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da215d64-40fa-4bd8-8487-2c160be31ae1",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2b95f9cc-d3c2-4445-bf1f-f29444dbd11d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5448771b-2fb0-4280-8a02-7502cf667ae2",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
